﻿using System.Windows.Forms;
using System.Threading;
using System;

namespace LED_Tester
{
    public abstract class SplashScreenApplicationContext : ApplicationContext 
    {
        private Form frmSplashScreen;
        private Form frmMain;
        private System.Timers.Timer tmrSplashScreen;
        private int timeValue = 5000;
        private bool isCloes = false;
        private delegate void dlgDispose();

        public SplashScreenApplicationContext()
        {
            this.showSplashScreen();
            this.showMain();
        }

        protected abstract void onCreateSplashScreenForm();

        protected abstract void onCreateMainForm();

        protected abstract void setTimeValue();

        protected Form FrmSplashScreen
        {
            set
            {
                this.frmSplashScreen = value;
            }
        }

        protected Form FrmMain
        {//在派生类中重写OnCreateMainForm方法，在MainFormLoad方法中调用OnCreateMainForm方法 
            //  ,在这里才会真正调用Form1(主窗体)的构造函数，即在启动窗体显示后再调用主窗体的构造函数 
            //  ，以避免这种情况:主窗体构造所需时间较长,在屏幕上许久没有响应，看不到启动窗体       
            set
            {
                this.frmMain = value;
            }
        }

        protected int TimeValue
        {//未设置启动画面停留时间时，使用默认时间 
            set
            {
                if (value != 0)
                {
                    this.timeValue = 1000 * value;
                }
            }
        }

        private void showSplashScreen()
        {
            this.setTimeValue();
            this.onCreateSplashScreenForm();
            this.tmrSplashScreen = new System.Timers.Timer((double)this.timeValue);
            tmrSplashScreen.Elapsed += new System.Timers.ElapsedEventHandler(this.displaySplashScreenTimeUp);
            this.tmrSplashScreen.AutoReset = false;
            Thread threadDisplaySplashScreen = new Thread(displaySplashScreen);
            threadDisplaySplashScreen.Start();
        }

        private void displaySplashScreen()
        {
            this.tmrSplashScreen.Enabled = true;
            Application.Run(this.frmSplashScreen);
        }

        private void displaySplashScreenTimeUp(object sender, System.Timers.ElapsedEventArgs e)
        {
            this.tmrSplashScreen.Dispose();
            this.tmrSplashScreen = null;
            this.isCloes = true;
        }

        private void showMain()
        {
            this.onCreateMainForm();

            while (!(this.isCloes))
            {
                Application.DoEvents();
            }

            dlgDispose dispose = new dlgDispose(this.frmSplashScreen.Dispose);
            Thread.Sleep(20);
            this.frmSplashScreen.Invoke(dispose);
            this.frmSplashScreen = null;
            //必须先显示，再激活，否则主窗体不能在启动窗体消失后出现 
            this.frmMain.Show();
            this.frmMain.Activate();
            this.frmMain.Closed += new EventHandler(frmMain_Closed);
        }

        private void frmMain_Closed(object sender, EventArgs e)
        {
            base.ExitThread();
        } 
    }
}
